﻿using APP.Image;
using APP.Win32;
using ScreenCapture.Model;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace ScreenCapture
{
    /// <summary>
    /// Interaction logic for CaptureWindow.xaml
    /// </summary>
    public partial class CaptureWindow : Window
    {
        bool CaptureInnerWindow = false;
        public CaptureWindow()
        {
            InitializeComponent();

            ScreenInfos.Clear();
            foreach (var tempScreen in System.Windows.Forms.Screen.AllScreens)
            {
                var bitmap = CaptureScreen(tempScreen.Bounds.X, tempScreen.Bounds.Y, tempScreen.Bounds.Width, tempScreen.Bounds.Height);
                var tempScreenInfo = new ScreenInfo();
                tempScreenInfo.Screen = tempScreen;
                tempScreenInfo.ScreenImage = bitmap;
                tempScreenInfo.Scale = Win32Helper.GetCurrentDpiScale();
                double Dpirate = ScreenInformations.GetDPIRate(tempScreen.Bounds.X, tempScreen.Bounds.Y);
                tempScreenInfo.pixDpi = Dpirate;
                ScreenInfos.Add(tempScreenInfo);
            }

            //var position = System.Windows.Forms.Cursor.Position;
            //CurrentScreen = ScreenInfos.First(x => CursorInScreen(x.Screen, position.X, position.Y));
            //timer = new Timer();
            //timer.Elapsed += Timer_Elapsed;
            //timer.Interval = TimeSpan.FromMilliseconds(300).TotalMilliseconds;
            //timer.Start();
        }
        public CaptureWindow(bool FullScreen) : this()
        {
            CaptureInnerWindow = false;
            var screen = System.Windows.Forms.Screen.AllScreens.First(x => x.Primary);
            var Scale = Win32Helper.GetCurrentDpiScale();
            this.Width = screen.Bounds.Width / Scale.X;
            this.Height = screen.Bounds.Height / Scale.X;
            this.Left = screen.Bounds.Left / Scale.X;
            this.Top = screen.Bounds.Top / Scale.X;

            bitmap = CaptureScreen(screen);
            origin.Source = back.Source = ImageHelper.ChangeBitmapToImageSource(bitmap);
        }
        WindowInfo WindowInfo;
        public CaptureWindow(WindowInfo windoInfo) : this()
        {
            CaptureInnerWindow = true;
            WindowInfo = windoInfo;
            var Scale = Win32Helper.GetCurrentDpiScale();
            this.Width = windoInfo.WindowRect.Width / Scale.X;
            this.Height = windoInfo.WindowRect.Height / Scale.X;
            this.Left = windoInfo.WindowRect.Left / Scale.X;
            this.Top = windoInfo.WindowRect.Top / Scale.X;
            bitmap = CaptureScreen(windoInfo.WindowRect);
            origin.Source = back.Source = ImageHelper.ChangeBitmapToImageSource(bitmap);
        }


        private List<ScreenInfo> ScreenInfos { get; set; } = new List<ScreenInfo>();


        private class ScreenInfo
        {
            public System.Drawing.Bitmap ScreenImage { get; set; }

            public System.Windows.Forms.Screen Screen { get; set; }

            public Win32Helper.DpiScaleF Scale { get; set; }
            public double pixDpi { get; set; }
            public Graphics formGraphics { get; set; }

        }

        private bool CursorInScreen(System.Windows.Forms.Screen screen, double x, double y)
        {
            return screen.Bounds.Left < x
               && screen.Bounds.Right > x
               && screen.Bounds.Top < y
               && screen.Bounds.Bottom > y;
        }


        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            var position = System.Windows.Forms.Cursor.Position;
            double x = position.X;
            double y = position.Y;

            var tempScreen = System.Windows.Forms.Screen.AllScreens.Where(screen => CursorInScreen(screen, x, y)).FirstOrDefault();
            if (tempScreen != null)
            {
                if (CurrentScreen.Screen == tempScreen)
                {
                    return;
                }
                var currentScreenInfo = ScreenInfos.FirstOrDefault(screen => screen.Screen == tempScreen);
                if (currentScreenInfo == null)
                {
                    return;
                }

                var width = tempScreen.Bounds.Width;
                var height = tempScreen.Bounds.Height;
                currentScreenInfo.Scale = Win32Helper.GetCurrentDpiScale();

                CurrentScreen = currentScreenInfo;


                this.Dispatcher.Invoke(() =>
                {
                    this.Width = width;
                    this.Height = height;
                    this.Left = tempScreen.Bounds.X;
                    this.Top = tempScreen.Bounds.Y;


                    back.Width = width / currentScreenInfo.pixDpi;
                    back.Height = height / currentScreenInfo.pixDpi;
                    back.Source = null;
                    origin.Source = back.Source = ImageHelper.ChangeBitmapToImageSource(currentScreenInfo.ScreenImage);

                });

            }
        }

        Timer timer;
        System.Drawing.Bitmap bitmap;
        bool IsSelecting = false;
        System.Drawing.Point startPoint;
        public System.Drawing.Rectangle selectImageRect;
        public System.Drawing.Rectangle selectImageRectScale;
        ScreenInfo CurrentScreen;


        private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            IsSelecting = true;
            mypop.IsOpen = false;
            if (IsSelecting)
            {
                startPoint = System.Windows.Forms.Cursor.Position;
                if (CaptureInnerWindow)
                {
                    startPoint.Offset(-WindowInfo.WindowRect.Left, -WindowInfo.WindowRect.Top);
                }
            }
        }


        private void Grid_MouseMove(object sender, MouseEventArgs e)
        {
            var Scale = Win32Helper.GetCurrentDpiScale();
            if (IsSelecting)
            {
                var position = System.Windows.Forms.Cursor.Position;
                if (CaptureInnerWindow)
                {
                    position.Offset(-WindowInfo.WindowRect.Left, -WindowInfo.WindowRect.Top);
                }
                double x = Math.Min(position.X, startPoint.X);
                double y = Math.Min(position.Y, startPoint.Y);
                double width = Math.Abs(position.X - startPoint.X);
                double height = Math.Abs(position.Y - startPoint.Y);

                selectImageRect = new System.Drawing.Rectangle((int)x, (int)y, (int)width, (int)height);

                double scrleX = x / Scale.X;
                double scrleY = y / Scale.X;
                double scrleWidth = width / Scale.X;
                double scrleHeight = height / Scale.X;


                selectRange.Margin = new Thickness(scrleX, scrleY, 0, 0);
                selectRange.Width = scrleWidth;
                selectRange.Height = scrleHeight;
                selectImageRectScale = new System.Drawing.Rectangle((int)scrleX, (int)scrleY, (int)scrleWidth, (int)scrleHeight);


                this.Dispatcher.InvokeAsync(() =>
                {
                    origin.Margin = new Thickness(-scrleX, -scrleY, 0, 0);
                    origin.Width = this.Width;
                    origin.Height = this.Height;
                });
            }

        }
        public static System.Drawing.Bitmap CapturePrimaryScreen()
        {
            var screen = System.Windows.Forms.Screen.AllScreens.First(x => x.Primary);
            return CaptureScreen(screen.Bounds.X, screen.Bounds.Y, screen.Bounds.Width, screen.Bounds.Height);
        }

        public static System.Drawing.Rectangle CapturePrimaryScreenRectangle()
        {
            var screen = System.Windows.Forms.Screen.AllScreens.First(x => x.Primary);
            return screen.Bounds;
        }

        public static System.Drawing.Bitmap CaptureScreen(System.Windows.Forms.Screen screen)
        {
            return CaptureScreen(screen.Bounds.X, screen.Bounds.Y, screen.Bounds.Width, screen.Bounds.Height);
        }
        public static System.Drawing.Bitmap CaptureScreen(System.Drawing.Rectangle rect)
        {
            return CaptureScreen(rect.X, rect.Y, rect.Width, rect.Height);
        }
        /// <summary>
        /// 截取屏幕
        /// </summary>
        /// <param name="x">起点X坐标</param>
        /// <param name="y">起点Y坐标</param>
        /// <param name="width">截取宽度</param>
        /// <param name="height">截取高度</param>
        /// <returns></returns>
        private static System.Drawing.Bitmap CaptureScreen(double x, double y, double width, double height)
        {
            int ix = Convert.ToInt32(x);
            int iy = Convert.ToInt32(y);
            int iw = Convert.ToInt32(width);
            int ih = Convert.ToInt32(height);

            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(iw, ih);
            System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap);
            graphics.CopyFromScreen(ix, iy, 0, 0, new System.Drawing.Size(iw, ih));
            graphics.Dispose();
            return bitmap;
        }


        public VisualBrush GetVisualBrush()
        {
            VisualBrush brush = new VisualBrush();
            brush.Stretch = Stretch.Fill;
            brush.Visual = origin;
            brush.Opacity = 1;
            return brush;
        }

        private void Grid_MouseUp(object sender, MouseButtonEventArgs e)
        {
            IsSelecting = false;
            if (selectImageRect.Width != 0 && selectImageRect.Height != 0)
            {
                mypop.IsOpen = true;
            }
        }


        private void Esc_Click(object sender, ExecutedRoutedEventArgs e)
        {
            //this.Close();
            DialogResult = false;
        }

        private void Confirm_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
        }


        public System.Drawing.Bitmap ShowDialog()
        {
            var result = base.ShowDialog();
            if (result == true)
            {
                var Scale = Win32Helper.GetCurrentDpiScale();
                var scale = Scale.X;
                //scale = 1;
                double scrleX = selectImageRect.X;
                double scrleY = selectImageRect.Y;
                double scrleWidth = selectRange.Width * scale;
                double scrleHeight = selectRange.Height * scale;

                var selectImageRect1 = new System.Drawing.Rectangle((int)scrleX, (int)scrleY, (int)scrleWidth, (int)scrleHeight);
                var selectImage = ImageHelper.DrawCaptureImage(bitmap, selectImageRect1);
                return selectImage;
            }
            else
            {
                return null;
            }
        }
    }
}
